iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Software Development

Android 工具箱開發系列 第 9 篇

Day 9 處理 Shizuku 授權和生死

  • 分享至 

  • xImage
  •  

昨天已經能看 Shizuku 有沒有在跑,但要手動更新

這很不智慧
就像門鈴壞掉,每五分鐘自己開門看有沒有人

今天改成讓 Shizuku 主動通知我們

監聽 Binder 狀態

Shizuku 提供三個重要事件:

private val binderReceived =
    Shizuku.OnBinderReceivedListener { refresh() }

private val binderDead =
    Shizuku.OnBinderDeadListener {
        shellService = null
        refresh()
    }

private val permissionResult =
    Shizuku.OnRequestPermissionResultListener { _, _ ->
        refresh()
    }

分別代表:

  • Binder 來了,服務上班了
  • Binder 死了,服務下班了
  • 使用者決定要不要授權

註冊時要用 Sticky 版本:

fun register() {
    Shizuku.addBinderReceivedListenerSticky(binderReceived)
    Shizuku.addBinderDeadListener(binderDead)
    Shizuku.addRequestPermissionResultListener(permissionResult)
    refresh()
}

因為 Binder 可能在 Application.onCreate() 前就送到了

不用 Sticky 的話,就像派對結束後才去門口等邀請函
你可以等很久,真的

這些 listener 放在 Application 註冊,不要綁在 Activity
不然 Activity 被回收,監聽也跟著登出人生

補上授權狀態

服務活著,不代表我們有權使用:

private fun currentState(): ShizukuState {
    val alive = runCatching {
        Shizuku.pingBinder()
    }.getOrDefault(false)

    if (!alive) {
        return if (isShizukuInstalled())
            ShizukuState.NotRunning
        else
            ShizukuState.NotInstalled
    }

    if (Shizuku.isPreV11())
        return ShizukuState.Unsupported

    val granted = Shizuku.checkSelfPermission() ==
        PackageManager.PERMISSION_GRANTED

    return if (granted)
        ShizukuState.Ready
    else
        ShizukuState.PermissionRequired
}

需要授權時呼叫:

fun requestPermission() {
    runCatching {
        Shizuku.requestPermission(REQUEST_CODE)
    }
}

使用者按下同意後,listener 會收到結果,重新整理狀態,畫面就會自己變成 Ready

終於不用一直問「好了沒」
連 App 都受不了這種對話

為什麼用 StateFlow

ShizukuManager 用 StateFlow,不直接用 Compose 的 mutableStateOf

因為它不該知道畫面是 Compose、Widget 還是其他東西
資料層如果開始管 UI,最後會像親戚群組一樣,什麼都管

Compose 裡再用:

collectAsStateWithLifecycle()

這樣畫面進背景後會停止收集,比較不浪費資源

完成後記得測:

  • 沒安裝 Shizuku
  • 有安裝但沒啟動
  • 已啟動但沒授權
  • 已授權
  • 執行中突然被停止

如果 Shizuku 停掉後畫面會自己更新,就代表 Binder 的生死我們接住了

明天把這些狀態做成真正的畫面
不再只用一行 Text 敷衍使用者


上一篇
Day 8 把 Shizuku 接進專案
系列文
Android 工具箱開發 共 9 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言